import { Injectable } from '@angular/core';
import { Farm } from "../entity/farm.model";
import { Menu } from "../entity/menu.model";
import { User } from "../entity/user.model";
import { ParamDict, MenuParamDict } from "../entity/menu-param-dict.model";
import { Company } from "../entity/company.model";
import { UserProfile } from "../entity/user-profile.model";
import { TagDict } from "../entity/tag-dict.model";
import { SetofkeyDict, SetofvalueDict } from "../entity/setof-dict.model";
import { TagDictService } from "./tag-dict.service";
import { SetofDictService } from "./setof-dict.service";
import { MenuParamDictService } from "./menu-param-dict.service";
import { Http } from "@angular/http";
import { Observable, Subject } from "rxjs/Rx";
import { AppConfig } from "../config";


@Injectable()
export class ApplicationService {
    private _sessionStorage: Storage;
    private _localStorage: Storage;
    private _location: Location;
    private _currentUserFarms: Farm[];
    private _currentMenuParams: ParamDict;
    private _menuParams: MenuParamDict;
    private _tagDict: TagDict;
    private _setKey: SetofkeyDict;
    private _setValue: SetofvalueDict;
    private _appConfigData: AppConfigData;
    public currentMenuParamsSubject: Subject<ParamDict> = new Subject<ParamDict>();
    public _currentApplicationParams: ParamDict;
    /**
     * 数据参数是否初始化完成
     *
     * @readonly
     * @type {User}
     * @memberof ApplicationService
     */
    public get initApplicationCompleted(): boolean {
        return this.sessionStorageGetItem<boolean>("initApplicationCompleted");
    }
    public set initApplicationCompleted(value: boolean) {
        this.sessionStorageSetItem("initApplicationCompleted", value);
    }
    /**
     * 应用程序配置是否初始化完成
     *
     * @readonly
     * @type {User}
     * @memberof ApplicationService
     */
    public get initAppConfigDataCompleted(): boolean {
        return this.sessionStorageGetItem<boolean>("initAppConfigDataCompleted");
    }
    public set initAppConfigDataCompleted(value: boolean) {
        this.sessionStorageSetItem("initAppConfigDataCompleted", value);
    }
    /**
     * 获得当前网站基地址
     *
     * @type {Location}
     * @memberof ApplicationService
     */
    public get baseHref(): string {
        return this._location.href;
    }
    /**
     * 获得window.location对象
     *
     * @type {Location}
     * @memberof ApplicationService
     */
    public get location(): Location {
        return this._location;
    }
    /**
     * 获取或设置当前用户
     *
     * @readonly
     * @type {User}
     * @memberof ApplicationService
     */
    public get currentUser(): User {
        return this.sessionStorageGetItem<User>("currentUser");
    }
    public set currentUser(value: User) {
        this.sessionStorageSetItem("currentUser", value);
    }

    public get callbackURL(): string {
        return this.sessionStorageGetItem<string>("callbackURL");
    }
    public set callbackURL(value: string) {
        this.sessionStorageSetItem("callbackURL", value);
    }

    
    /**
     * 获取或设置当前用户
     *
     * @readonly
     * @type {UserProfile}
     * @memberof ApplicationService
     */
    public get currentUserProfile(): UserProfile {
        return this.sessionStorageGetItem<UserProfile>("currentUserProfile");
    }
    public set currentUserProfile(value: UserProfile) {
        this.sessionStorageSetItem("currentUserProfile", value);
    }

    /**
     * 获取或设置当前用户所属公司
     *
     * @readonly
     * @type {Company}
     * @memberof ApplicationService
     */
    public get currentCompany(): Company {
        return this.sessionStorageGetItem<Company>("currentCompany");
    }
    public set currentCompany(value: Company) {
        this.sessionStorageSetItem("currentCompany", value);
    }
    /**
     * 获取或设置当前用户拥有的风场权限
     *
     * @readonly
     * @type {Farm[]}
     * @memberof ApplicationService
     */
    public get currentUserFarms(): Farm[] {
        if (!this._currentUserFarms) {
            this._currentUserFarms = this.sessionStorageGetItem<Farm[]>("currentUserFarms");
        }
        return this._currentUserFarms
    }
    public set currentUserFarms(value: Farm[]) {
        this.sessionStorageSetItem("currentUserFarms", value);
        this._currentUserFarms = value;
    }
    /**
     * 获取或设置当前菜单
     *
     * @type {Menu}
     * @memberof ApplicationService
     */
    public get currentMenu(): Menu {
        return this.sessionStorageGetItem<Menu>("currentMenu");
    }
    /**
     * 设置当前菜单
     * 同时根据菜单ID查询菜单参数集合完成菜单参数写入
     * @memberof ApplicationService
     */
    public set currentMenu(value: Menu) {
        this.sessionStorageSetItem("currentMenu", value);
        try {
            let menuParams = this.menuParams[value.menuId];
            if (menuParams) {
                
                this.currentMenuParams = menuParams;
                this.currentMenuParamsSubject.next(this.currentMenuParams);
            }
            else {
                this.currentMenuParams = null;
                this.currentMenuParamsSubject.next(this.currentMenuParams);
            }
        }
        catch (err) {
            throw err;
        }
    }


    /**
     * 获取当前菜单参数
     *
     * @type {ParamDict}
     * @memberof ApplicationService
     */
    public get currentMenuParams(): ParamDict {
        if (!this._currentMenuParams) {
            this._currentMenuParams = this.sessionStorageGetItem<ParamDict>("currentMenuParams");
        }
        return this._currentMenuParams;
    }
    public set currentMenuParams(value: ParamDict) {
        this.sessionStorageSetItem("currentMenuParams", value);
        this._currentMenuParams = value;
    }
    /**
     * 获取系统菜单参数
     *
     * @type {ParamDict}
     * @memberof ApplicationService
     */
    public get currentApplicationParams(): ParamDict {
        if (!this._currentApplicationParams) {
            this._currentApplicationParams = this.sessionStorageGetItem<ParamDict>("currentApplicationParams");
        }
        return this._currentApplicationParams;
    }
    public set currentApplicationParams(value: ParamDict) {
        this.sessionStorageSetItem("currentApplicationParams", value);
        this._currentApplicationParams = value;
    }

    /**
    * 获取当前菜单参数
    *
    * @type {ParamDict}
    * @memberof ApplicationService
    */
    public get menuParams(): MenuParamDict {
        if (!this._menuParams) {
            this._menuParams = this.sessionStorageGetItem<MenuParamDict>("menuParams");
        }
        return this._menuParams;
    }
    public set menuParams(value: MenuParamDict) {
        this.sessionStorageSetItem("menuParams", value);
        this._menuParams = value;
    }




    /**
     * 获取或设置tag字典
     *
     * @type {TagDict}
     * @memberof ApplicationService
     */
    public get tagDict(): TagDict {
        if (!this._tagDict) {
            this._tagDict = this.sessionStorageGetItem<TagDict>("tagDict");
        }
        return this._tagDict
    }
    public set tagDict(value: TagDict) {
        this.sessionStorageSetItem("tagDict", value);
        this._tagDict = value;
    }
    /**
     * 获取或设置SetofkeyDict字典
     *
     * @type {TagDict}
     * @memberof ApplicationService
     */
    public get setKeyDict(): SetofkeyDict {
        if (!this._setKey) {
            this._setKey = this.sessionStorageGetItem<SetofkeyDict>("setKey");
        }
        return this._setKey;
    }
    public set setKeyDict(value: SetofkeyDict) {
        this.sessionStorageSetItem("setKey", value);
        this._setKey = value;
    }


    /**
     * 获取或设置SetofvalueDict字典
     *
     * @type {TagDict}
     * @memberof ApplicationService
     */
    public get setValueDict(): SetofvalueDict {
        if (!this._setValue) {
            this._setValue = this.sessionStorageGetItem<SetofvalueDict>("setValue");
        }
        return this._setValue;
    }
    public set setValueDict(value: SetofvalueDict) {
        this.sessionStorageSetItem("setValue", value);
        this._setValue = value;
    }


    /**
     * 获取或设置登录数据
     *
     * @type {LoginData}
     * @memberof ApplicationService
     */
    public get loginData(): LoginData {
        return this.localStorageGetItem<LoginData>("loginData");
    }
    public set loginData(value: LoginData) {
        this.localStorageSetItem("loginData", value);
    }

    /**
     * 获取或设置用户token
     *
     * @type {LoginData}
     * @memberof ApplicationService
     */
    public get userToken(): string {
        return this.localStorageGetItem<string>("userToken");
    }
    public set userToken(value: string) {
        this.localStorageSetItem("userToken", value);
    }

    /**
     * 获取或设置 App 配置信息
     *
     * @type {AppConfig}
     * @memberof ApplicationService
     */
    public get appConfigData(): AppConfigData {
        if (!this._appConfigData) {
            this._appConfigData = this.sessionStorageGetItem<AppConfigData>("appConfigData");
            if (this._appConfigData) {
                AppConfig.APP_TITLE = this._appConfigData.appTitle;
                AppConfig.APP_SUBTITLE = this._appConfigData.appSubTitle;
                AppConfig.APP_NAME = this._appConfigData.appName;
                AppConfig.APP_SUBNAME = this._appConfigData.appSubName;
                AppConfig.APP_LOG = this._appConfigData.appLog;
                AppConfig.APP_FAVICON = this._appConfigData.appFavicon;
                AppConfig.APP_RESTFUL = this._appConfigData.appRestful;
                AppConfig.APP_WEBSOCKET = this._appConfigData.appWebSocket;
                AppConfig.APP_RANDOM = this._appConfigData.appRandom;
                AppConfig.APP_COMPANY = this._appConfigData.appCompany;
                AppConfig.APP_REPORT = this.appConfigData.appReport;
                AppConfig.APP_3D = this.appConfigData.app3D;
                AppConfig.APP_STATION = this.appConfigData.appStation;
                AppConfig.APP_ISSHOWERR = this.appConfigData.isShowErr;
            }
        }
        return this._appConfigData;
    }
    public set appConfigData(value: AppConfigData) {
        this.sessionStorageSetItem("appConfigData", value);
        this._appConfigData = value;
    }



    /**
     * Creates an instance of ApplicationService.
     * @param {MenuParamDictService} menuParamDictService
     * @param {SetofDictService} setofDictService
     * @param {TagDictService} tagDictService
     * @memberof ApplicationService
     */
    constructor(
        private http: Http,
        private menuParamDictService: MenuParamDictService,
        private setofDictService: SetofDictService,
        private tagDictService: TagDictService,
    ) {
        if (!window.sessionStorage)
            throw new Error("当前浏览器不支持 window.sessionStorage ！");
        if (!window.localStorage)
            throw new Error("当前浏览器不支持 window.localStorage ！");
        this._localStorage = window.localStorage;
        this._sessionStorage = window.sessionStorage;
        this._location = window.location;

        let self = this;
        //监听窗口关闭或刷新事件
        window.onbeforeunload = function () {
            self.currentMenuParamsSubject.unsubscribe();
        }
    }


    /**
     * 初始化应用配置文件
     *
     * @returns {Observable<Result>}
     * @memberof ApplicationService
     */
    public initAppConfigData(): Observable<Result> {

        let configUrl = `assets/config/config.json?time=${(new Date()).getTime()}`;
        return Observable.create(observer => {
            this.http.get(configUrl).subscribe(
                next => {
                    try {
                        this.appConfigData = JSON.parse((next as any)._body);
                        AppConfig.APP_TITLE = this.appConfigData.appTitle;
                        AppConfig.APP_SUBTITLE = this.appConfigData.appSubTitle;
                        AppConfig.APP_NAME = this.appConfigData.appName;
                        AppConfig.APP_SUBNAME = this.appConfigData.appSubName;
                        AppConfig.APP_LOG = this.appConfigData.appLog;
                        AppConfig.APP_FAVICON = this.appConfigData.appFavicon;
                        AppConfig.APP_RESTFUL = this.appConfigData.appRestful;
                        AppConfig.APP_WEBSOCKET = this.appConfigData.appWebSocket;
                        AppConfig.APP_RANDOM = this.appConfigData.appRandom;
                        AppConfig.APP_COMPANY = this.appConfigData.appCompany;
                        AppConfig.APP_REPORT = this.appConfigData.appReport;
                        AppConfig.APP_3D = this.appConfigData.app3D;
                        AppConfig.APP_STATION = this.appConfigData.appStation;
                        AppConfig.APP_ISSHOWERR = this.appConfigData.isShowErr;
                        this.initAppConfigDataCompleted = true;
                        let result: Result = {
                            success: true,
                            message: "初始化配置文件成功。"
                        }
                        observer.next(result);
                    }
                    catch (error) {
                        observer.error(error);
                    }
                },
                error => {
                    observer.error(error);
                });
        });
    }


    /**
     * 初始化应用程序参数
     *
     * @param {User} currentUser
     * @param {UserProfile} currentUserProfile
     * @param {Company} currentCompany
     * @param {Farm[]} currentUserFarms
     * @memberof ApplicationService
     */
    public initApplicationData(
        currentUser: User,
        currentUserProfile: UserProfile,
        currentCompany: Company,
        currentUserFarms: Farm[],
        // callbackURL:string
        ): Observable<Result> {            
        return Observable.create(observer => {
         
            this.currentUser = currentUser;
            this.currentUserProfile = currentUserProfile;
            this.currentCompany = currentCompany;
            this.currentUserFarms = currentUserFarms;
            let menuParam = this.menuParamDictService.initData();
            let setofDict = this.setofDictService.initData();
            let tagDict = this.tagDictService.initData();
            Promise.all([menuParam, setofDict, tagDict])
                .then(res => {
                    try {                        
                        this.menuParams = this.menuParamDictService.menuParamDict;
                        this.tagDict = this.tagDictService.getTag;
                        this.setKeyDict = this.setofDictService.getSetofValues;
                        this.setValueDict = this.setofDictService.getSetofValue;
                        this.initApplicationCompleted = true;
                        this.currentApplicationParams = this.menuParamDictService.menuParamDict['0'];
                        // this.callbackURL = window.location.href.split("callbackURL=")[1];
                        observer.next({
                            success: true,
                            message: "初始化配置文件成功。"
                        });
                    }
                    catch (error) {
                        this.initApplicationCompleted = false;
                        observer.error(error);
                    }
                })
                .catch(err => {
                    this.initApplicationCompleted = false;
                    observer.error(err);
                })
        });

    }

    /**
     * 获得浏览器sessionStorage获得存储值并且转换为相应的对象
     *
     * @private
     * @template T
     * @param {string} key
     * @returns {T}
     * @memberof ApplicationService
     */
    public sessionStorageGetItem<T>(key: string): T {
        try {
            let json = this._sessionStorage.getItem(key);
            if (json && json != "") {
                return JSON.parse(json);
            }
            return null;
        }
        catch (err) {
            throw err;
        }
    }

    /**
     * 往浏览器 sessionStorage 对象写入值
     * 如果值为空增移除对象
     * @private
     * @param {string} key
     * @param {*} value
     * @memberof ApplicationService
     */
    public sessionStorageSetItem(key: string, value: any) {
        try {
            if (value != null) {
                this._sessionStorage.setItem(key, JSON.stringify(value));
            }
            else {
                this._sessionStorage.removeItem(key);
            }
        }
        catch (err) {
            throw err;
        }
    }
    /**
     * 获得浏览器 localStorage 获得存储值并且转换为相应的对象
     *
     * @private
     * @template T
     * @param {string} key
     * @returns {T}
     * @memberof ApplicationService
     */
    public localStorageGetItem<T>(key: string): T {
        try {
            let json = this._localStorage.getItem(key);
            if (json && json != "") {
                return JSON.parse(json);
            }
            return null;
        }
        catch (err) {
            throw err;
        }
    }
    /**
     * 往浏览器 localStorage 对象写入值
     * 如果值为空增移除对象
     * @private
     * @param {string} key
     * @param {*} value
     * @memberof ApplicationService
     */
    public localStorageSetItem(key: string, value: any) {
        try {
            if (value != null) {
                this._localStorage.setItem(key, JSON.stringify(value));
            }
            else {
                this._localStorage.removeItem(key);
            }

        }
        catch (err) {
            throw err;
        }
    }


    /**
     * 清空
     *
     * @memberof ApplicationService
     */
    public clear() {
        let loginData: LoginData = this.loginData;
        loginData.auto = false;
        loginData.password = "";
        this.loginData = loginData;
        this._sessionStorage.clear();
        this.initAppConfigDataCompleted = false;
        this.initApplicationCompleted = false;
    }


}

export interface LoginData {
    userName: string;
    password: string;    
    auto: boolean;
    loginState: boolean;
}

export interface AppConfigData {
    /**
     * APP 名称
     *
     * @static
     * @type {string}
     * @memberof AppConfig
     */
    appName: string;
    /**
     * APP 子名称
     *
     * @static
     * @type {string}
     * @memberof AppConfig
     */
    appSubName: string;
    /**
     * APP 描述信息
     *
     * @type {string}
     * @memberof AppConfig
     */
    appDescription: string;
    /**
     * APP log
     *
     *  @type {string}
     * @memberof AppConfig
     */
    appLog: string;
    /**
     * APP 小图标
     *
     * @type {string}
     * @memberof AppConfig
     */
    appFavicon: string;
    /**
     * APP 标题
     *
     * @memberof AppConfig
     */
    appTitle: string;
    /**
     * APP 子标题
     *
     * @type {string}
     * @memberof AppConfig
     */
    appSubTitle: string;
    /**
     * APP http请求的基地址
     *
     * @type {string}
     * @memberof AppConfig
     */
    appRestful: string;
    /**
     * APP websocket请求的基地址
     *
     * @type {string}
     * @memberof AppConfig
     */
    appWebSocket: string;
    /**
     * 调用 websocket是开启随机数
     * true:开启随机数
     * false:不开启随机数
     * @static
     * @type {boolean}
     * @memberof AppConfig
     */
    appRandom: boolean;

    /**
     * APP 公司省份地图配置项（广东：gd）
     * @static
     * @type {string}
     * @memberof AppConfig
     */
    appCompany: string;
    /**
     * APP 报表基地址
     *
     * @type {string}
     * @memberof AppConfigData
     */
    appReport: string;
    /**
     * 3d地址 (发布的时候该地址)
     *
     * @static
     * @type {string}
     * @memberof AppConfig
     */
    app3D: string;
    /**
    * 升压站地址 (发布的时候该地址)
    *
    * @static
    * @type {string}
    * @memberof AppConfig
    */
    appStation: string;

    /**
    * 是否心事错误信息
    *
    * @static
    * @type {string}
    * @memberof AppConfig
    */
    isShowErr: boolean;
}

export interface Result {
    /**
     * 是否成功
     *
     * @type {boolean}
     * @memberof Result
     */
    success: boolean;
    /**
     * 数据对象
     *
     * @type {boolean}
     * @memberof Result
     */
    data?: any;
    /**
     * 消息
     *
     * @type {boolean}
     * @memberof Result
     */
    message?: string;
    /**
     * 错误信息
     *
     * @type {boolean}
     * @memberof Result
     */
    error?: Error;
}



// WEBPACK FOOTER //
// ./src/app/service/application.service.ts